package ge.modules.logics;

import java.util.ArrayList;

import ge.engine.Log;
import ge.engine.Positionable;
import ge.engine.PositionableArea;

import ge.lowlevel.Vector;
import ge.modules.Module;
import ge.modules.events.CollisionListener;

/**
 * 
 * @author Abel
 * 	Solid Square is an enrichment of SquareCollide Class.
 *  This class work with the events and collisions to make it sure
 *  anything it's never inside itself. By two ways: putting out the other object
 *  or moving itself (Depending if it's fixed or not).
 *  
 *  Implements PositionableArea, but it is only an abstraction over the area you
 *  can get with getArea() 
 * 
 */
public class SolidSquare implements Module, PositionableArea {

	private SquareCollide area;
	private CollisionListener colisionlistener;
	private boolean fixed;
	
	/**
	 * New solid area. Fixed behavior is by default false.
	 * @param width Width of area
	 * @param height Height of area
	 * @param id why you and collision engine are going to identify it
	 */
	public SolidSquare(double width, double height, int id)
	{
			area = new SquareCollide(width, height,id);
			colisionlistener = new CollisionListener(area);
			fixed = false;
			area.enableCollide(true);
	}		
	/**
	 * New solid area. Id by default is 0, and fixed behavior by default is false
	 * @param width Width of area
	 * @param height Height of area
	 *  
	 */
	public SolidSquare(double width, double height)
	{
			area = new SquareCollide(width, height);
			colisionlistener = new CollisionListener(area);
			fixed = false;
			area.enableCollide(true);
	}	
	/**
	 * @return Fixed property
	 */
	public boolean isFixed() {
		return fixed;
	}
	/**
	 *  Fixed establish the behavior in a collision, if the object is fixed
	 *  it will put out the strange. If not, it will apart, moving out.
	 * @param fixed True become it fixed
	 */
	public void setFixed(boolean fixed) {
		this.fixed = fixed;
	}
	/**
	 * 	Solid Square is based in one SquareCollide area. You can get the area
	 * to make modification in its features.
	 * @return The area of collision.
	 */
	public SquareCollide getArea()
	{
		return area;
		
	}
	/**
	 * 	Calls to area attachedTo function, whenever the logic element is moved, the attached element will
	 * be moved too.
	 * @param element
	 */
	public void attachedTo(Positionable element)
	{
		area.attachedTo(element);
	}
	@Override
	public void update()
	{
		area.update();
		colisionlistener.update();
		ArrayList<Vector> colisions = colisionlistener.collide();
		GeomCollideFigure fix,move;
		for(Vector v : colisions)
		{
			fix = (fixed?area:v.figure);
			move = (fixed?v.figure:area);
			if(!fixed)
			{
				if(v.collideUp())
					move.setPos(move.X,fix.getY()+fix.getHeight());
				else if(v.collideDown())
					move.setPos(move.X,fix.getY()-move.getHeight());
				else if(v.collideRight())
					move.setPos(fix.getX()-move.getWidth(), move.getY());
				else
					move.setPos(fix.getWidth()+fix.getX(), move.getY());
			}
			else
			{
				if(v.collideUp())
					move.setPos(move.X,fix.getY()-move.getHeight());
				else if(v.collideDown())
					move.setPos(move.X,fix.getY()+fix.getHeight());
				else if(v.collideRight())
					move.setPos(fix.getWidth()+fix.getX(), move.getY());
				else
					move.setPos(fix.getX()-move.getWidth(), move.getY());
			}
		}

	}

	@Override
	public void draw() {
		 
		area.draw();
	}
	@Override
	public void setPos(double x, double y) {
		area.setPos(x, y);
		
	}
	@Override
	public double getX() {
		 
		return area.getX();
	}
	@Override
	public double getY() {
		 
		return area.getY();
	}
	@Override
	public double getWidth() {
		 
		return area.getWidth();
	}
	@Override
	public double getHeight() {
		 
		return area.getHeight();
	}
	@Override
	public void setArea(double width, double height) {
		area.setArea(width, height);
		
	}
	@Override
	public void delete() {
		 colisionlistener.delete();
		 area.delete();
	}

}
